/*
 * @Author: _oufen
 * @Date: 2023-07-11 20:23:19
 * @LastEditTime: 2023-07-20 10:41:22
 * @Description:  这是一个模板文件
 */
/**
 *************************************************************************************************************************
 * @file   openmv.c
 * @author  oufen
 * @version V1.0
 * @date    2023-07-10
 * @brief   OpenMV串口接收
 *************************************************************************************************************************
 * @attention
 * OpenMV使用的是串口3
 * RX   PC6     TX  PC7
 * 波特率   115200
 *************************************************************************************************************************
 */

/* Includes -------------------------------------------------------------------------------------------------------------*/
#include "openmv.h"
/* 定义 -----------------------------------------------------------------------------------------------------------------*/

// 串口3 接收解析
int OpenMv_Receive_Buff[6]; // 接收数据缓存
int16_t OpenMv_data1;       // 第一个为  有效数据1
int16_t OpenMv_data2;       // 第二个为  有效数据2
int16_t OpenMv_data3;       // 第三个为  有效数据3

/**
 * @brief   处理接收到的OpenMv数据
 * @param 	无
 * @retval  无
 */
void OpenMv_Get_Data(void) // 处理蓝牙接收的数据
{
    OpenMv_data1 = OpenMv_Receive_Buff[2];
    OpenMv_data2 = OpenMv_Receive_Buff[3];
    OpenMv_data3 = OpenMv_Receive_Buff[4];
}

/**
 * @brief   解析OpenMv发过来的数据
 * @param 	int16_t data  传入的接收数据
 * @retval  无
 */
void OpenMV_Receive_Data(int16_t data) // 解析数据
{
    int i;
    static uint8_t state = 0;
    if (state == 0 && data == 0xb3) // 第一个帧头
    {
        state = 1;
        OpenMv_Receive_Buff[0] = data;
    }
    else if (state == 1 && data == 0xb3) // 第二个帧头
    {
        state = 2;
        OpenMv_Receive_Buff[1] = data;
    }
    else if (state == 2) // 第一个有效数据
    {
        state = 3;
        OpenMv_Receive_Buff[2] = data;
    }
    else if (state == 3) // 第二个有效数据
    {
        state = 4;
        OpenMv_Receive_Buff[3] = data;
    }
    else if (state == 4) // 第三个有效数据
    {
        state = 5;
        OpenMv_Receive_Buff[4] = data;
    }
    else if (state == 5) // 检测是否接受到结束标志，检测接收帧尾
    {
        if (data == 0x5B)
        {
            state = 0;
            OpenMv_Receive_Buff[5] = data;
            OpenMv_Get_Data();
        }
        else if (data != 0x5B)
        {
            state = 0;
            for (i = 0; i < 6; i++)
            {
                OpenMv_Receive_Buff[i] = 0x00;
            }
        }
    }
    else
    {
        state = 0;
        for (i = 0; i < 6; i++)
        {
            OpenMv_Receive_Buff[i] = 0x00;
        }
    }
}

/**
 * @brief   发送给OpenMV数据包
 * @param 	uint8_t *str  data数组
 * @retval  无
 * 数据包格式   b3   b3  data1   data2   data3   5b
 */
void OpenMv_SendData(uint8_t *str) // b3 b3 data1 data2 data3 5b
{
    uint8_t i = 0;
    for (i = 0; i < 2; i++) // b3 b3
    {
        ROM_UARTCharPut(UART3_BASE, 0xb3);
    }

    for (i = 0; i < 3; i++) // 发送三位有效位
    {
        ROM_UARTCharPut(UART3_BASE, str[i]); // data1 data2 data3
    }

    ROM_UARTCharPut(UART3_BASE, 0x5b); // 0x5b
}

/**
 * @brief   串口3中断函数
 * @param 	无
 * @retval  无
 */
void UART3_Int_Handler(void) /*串口3中断函数*/
{

    char cThisChar;

    // 获取中断标志 原始中断状态 屏蔽中断标志
    uint32_t flag = ROM_UARTIntStatus(UART3_BASE, 1);
    // 清除中断标志
    ROM_UARTIntClear(UART3_BASE, flag);
    if (flag & UART_INT_RX)
        // UARTCharsAvail()判断FIFO是否还有数据
        while (UARTCharsAvail(UART3_BASE))
        {
            cThisChar = ROM_UARTCharGet(UART3_BASE); // 接收一个字符

            //  ROM_UARTCharPut(UART3_BASE, cThisChar); // 发送一个字符  这里要注意 如果测试其他串口功能的话需要 注释掉串口0的接收发送程序  因为可能会受影响
            //   后来实测 并不会受影响 测试成功

            OpenMV_Receive_Data(cThisChar); // 解析数据
            OpenMv_Get_Data();              // 获取数据
        }
}

/**
 * @brief   OpenMv对应串口3初始化
 * @param 	unsigned long ulBaud  波特率
 * @retval  无
 */
void OpenMv_Init(unsigned long ulBaud) /*串口3初始化*/
{

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);

    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); // 使能GPIO外设

    ROM_GPIOPinConfigure(GPIO_PC6_U3RX); // GPIO模式配置 PC6--RX PC7--TX
    ROM_GPIOPinConfigure(GPIO_PC7_U3TX);

    ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7); // GPIO的UART模式配置

    ROM_UARTConfigSetExpClk(UART3_BASE, ROM_SysCtlClockGet(), ulBaud,
                            (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                             UART_CONFIG_PAR_NONE)); // UART协议配置 波特率ulBaud 8位 1停止位  无校验位

    // UART禁用FIFO 默认FIFO Level为4/8 寄存器满8字节后产生中断
    // 禁用后接收1位就产生中断
    ROM_UARTFIFODisable(UART3_BASE);

    ROM_IntEnable(INT_UART3); // 使能UART3中断

    ROM_UARTIntEnable(UART3_BASE, UART_INT_RX); // 使能UART3接收中断

    UARTIntRegister(UART3_BASE, UART3_Int_Handler); // UART中断地址注册

    // 设置优先级
    ROM_IntPrioritySet(INT_UART3, USER_INT3); // 优先级为   0x60
}
/*****************************************************END OF FILE*********************************************************/
